# 题目
已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数。
不要使用系统的 Math.random()
方法。
# 概率重分配 & 拒绝采样
使用 rand7
生成10个同等概率的数字, 然后映射即可。
根据官方题解,我们可以调用两次 rand7
来生成等概率的[1,49]的数字, 只使用 [1,40]来作为rand10的采样, 如下图:
生成公式:
等概率的生成[1, X * Y]范围的随机数
- rand7() - 1 ==> 生成等概率的 {0,1,2,3,4,5,6} 其中一个
- (rand7() - 1)*7 ==> 生成等概率的 {0,7,14,21,28,35,42} 其中一个
- (rand7()-1)*7 + rand7() ==> 生成等概率的 [1,49] 其中一个
计算之后:
- 当出现 [1,40], 则转换成 [1,10] ==> sum%10 + 1
- 当出现 [41,49], 则重新生成
# 代码
var rand10 = function() {
let sum = 0;
do{
sum = (rand7()-1)*7 + rand7()
}while(sum>40)
return 1+sum%10
};